#include <QMessageBox>

#include "appmanager.h"

AppManager *AppManager::mInstance = NULL;

AppManager::AppManager():
    mDbw(NULL),
    mStyleLoader(NULL),
    mStyleIdDelegate4Tree(NULL),
    mStyleIdDelegate4Tab(NULL),
    // UI
    mStyleDialog(NULL),
    mMainWindow(NULL),
    mSettingsForm(NULL),
    mRecordForm(NULL),
    mAppSettings(NULL)
{
    mStylesLoaded = NoStylesLoaded;
}

AppManager::~AppManager()
{
    delete mMainWindow;
}

void AppManager::CreateInstance()
{
    if (mInstance == NULL)
    {
        mInstance = new AppManager();
        mInstance->setup();
    }
}

void AppManager::DestroyInstance()
{
    if (mInstance != NULL)
    {
        mInstance->saveSettings();
        delete mInstance;
    }
}

AppManager *AppManager::instance()
{
    return mInstance;
}

DBWorker* AppManager::dbWorker()
{
    return mDbw;
}

void AppManager::saveSettings()
{
    LOG( "AppManager::saveSettings", "Збереження налаштувань",  "" );
    // saving parameters through QSettings
    // about DB:
    mAppSettings->setValue("DbName", dbWorker()->dbName());
    // aobut styles:
    mAppSettings->setValue("StyleDir", styleLoader()->dir());
    // about MainWindow:
    mAppSettings->setValue("WinSize", mainWindow()->size());
    mAppSettings->setValue("IsWinFullScreen", false);
    mAppSettings->setValue("WinTopLeft", mainWindow()->pos());
}

void AppManager::setupSignals()
{
    connect(mDbw, SIGNAL(recordDeleted()),
            mMainWindow, SLOT(refreshViews()));

    connect(mDbw, SIGNAL(needRefresh()),
            mMainWindow, SLOT(refreshViews()));
}

void AppManager::setup()
{
    // Parameters for QSettings
    QString typicalDbName(QDir("bases").absoluteFilePath("my.sqlite"));
    QString typicalStyleDir("styles");
    QSize   typicalWinSize(QSize(650, 450));
    QPoint   typicalWinTopLeft(QPoint(100, 100));
    bool    typicalIsWinFullScreen = false;
    Q_UNUSED(typicalIsWinFullScreen);   // TODO: use it
    mAppSettings = new QSettings(ORGANIZATION, APP_NAME, this);
    if (mAppSettings != NULL)
    {
        LOG( "AppManager setup", "Створено AppSetting", "" );
        // TODO: work on all settings

        // check weather first execution
        if (mAppSettings->contains("DbName"))
        {   // QDisco have aready been executed on this computer
            typicalDbName = mAppSettings->value("DbName").toString();
            typicalDbName = QDir::toNativeSeparators(typicalDbName);

            typicalStyleDir = mAppSettings->value("StyleDir").toString();
            typicalStyleDir = QDir::toNativeSeparators(typicalStyleDir);

            typicalWinSize  = mAppSettings->value("WinSize").toSize();
            typicalIsWinFullScreen = mAppSettings->value("IsWinFullScreen").toBool();
            typicalWinTopLeft = mAppSettings->value("WinTopLeft").toPoint();
        }
    }

    // create & config DBWorker instance
    mDbw = new DBWorker(this);
    if (mDbw != NULL)
    {
        if ( QFile::exists(typicalDbName) )
        {
            // recent DB file exists, ask if needed to open recent DB
            QMessageBox msg;
            msg.setText("<h2>Підтвердіть відкриття БД</h2>");
            msg.setIcon(QMessageBox::Question);
            msg.setInformativeText(QString("Ви впевнені, що хочете завантажити файл <br /><i>%1</i>?")
                                   .arg(typicalDbName));
            msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
            msg.setDefaultButton(QMessageBox::Yes);
            int msgRes = msg.exec();
            if (msgRes == QMessageBox::Yes)
            {
                if (mDbw->openDb(typicalDbName))
                {
                    // DB is opened
                }
                else
                {
                    // DB is NOT opened, show message
                }
            }
        }
        else
        {
            // recent DB file doesn't exist
        }


        // TODO: LOT OF WORK HERE!!
        // +++++++++++++++++++++++++
        LOG( "AppManager setup",  "Створено DBManager", "");
    }
    else
        LOG( "AppManager setup", "Помилка створення DBManager", "");

    // create & config StyleloaderInstance
    mStyleLoader = new StyleLoader();
    if (mStyleLoader != NULL)
    {
        LOG("AppManager setup", "Cтворено StyleLoader", "" );

        mStyleLoader->setDir(typicalStyleDir);

        mStyleLoader->loadStyles(mStyles);
        switch (stylesLoaded())
        {
        case AllStylesLoaded:
            LOG( "appManager::setup", "Стилі успішно завантажені", "" ); break;
        case SomeStylesLoaded:
            LOG( "appManager::setup", "Увага! Не всі стилі успішно завантажені", "" );
            mStyleIdDelegate4Tree->generateFallStyleImg();
            break;
        case NoStylesLoaded:
            LOG( "appManager::setup", "Помилка! Жодного зі стилів не було завантажено!", "" ); break;
            mStyleIdDelegate4Tree->generateFallStyleImg();
            break;
        }
        createDelegateForStyles();
    }
    else
        LOG("AppManager setup", "Помилка створення StyleLoader", "" );

    // create & config SettingsForm
    mSettingsForm = new SettingsForm();
    if (mSettingsForm != NULL)
    {
        LOG( "AppManager setup", "Створено SettingsForm", "" );

        mSettingsForm->setStyleDir(typicalStyleDir);
        // loading styles into SettingsForm
        if (stylesLoaded() == AllStylesLoaded)      // TODO: check here if SomeStylesLoaded
            mSettingsForm->loadStyles(mStyles);
    }
    else
        LOG( "AppManager setup", "Помилка створення SettingsForm", "" );

    // creat & config MainWindow
    mMainWindow = new MainWindow();
    if (mMainWindow != NULL)
    {
        mMainWindow->setGeometry(0, 0, typicalWinSize.width(), typicalWinSize.height());
        mMainWindow->move(typicalWinTopLeft);
        mMainWindow->setupMenu();
        mMainWindow->setupWindow();
        LOG( "AppManager setup", "Створено MainWindow", "");
    }
    else
        LOG( "AppManager setup", "Помилка створення MainWindow", "");

    mRecordForm = new RecordForm();
    if (mRecordForm != NULL)
    {
        LOG( "AppManager setup", "Створено AddRecordForm", ""  );
    }
    else
        LOG( "AppManager setup", "Помилка створення AddRecordForm", "" );

    // CONFIG ALL CONNECTIONS
    setupSignals();

//    mMainWindow->refreshViews(); // TODO: wtf, get out of here!
}

void AppManager::createDelegateForStyles()
{
    LOG( "AppManager::createDelegateForStyles", "", "" );

    mStyleIdDelegate4Tree = new StyleIdDelegate(mStyles, true, this);
    mStyleIdDelegate4Tab  = new StyleIdDelegate(mStyles, false, this);
}
